<template>
  <div id="scene"></div>

  <div class="labeldiv alter">
    <div class='labelitem'>
      <div class='labelname'>系统有故障：</div>
      <div class='dot' id='Xtygz'></div>
    </div>
    <div class='labelitem'>
      <div class='labelname'>急停按钮：</div>
      <div class='dot' id='Jtan'></div>
    </div>
    <div class='labelitem'>
      <div class='labelname'>浸水信号：</div>
      <div class='dot' id='Jsxh'></div>
    </div>
  </div>

  <div class="labeldiv"></div>
</template>

<script setup>
import {
loginApi,
pollApi,
registerApi,
registerStatusApi,
startGetListApi
} from '@/api/api.js';
import { getIdx } from '@/api/utils.js';
import _ from 'lodash';
import { onMounted, ref, watch } from 'vue';

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer';
import { log } from 'three/examples/jsm/nodes/Nodes.js';


//初始化数据measureList和statusList
var indexMeasureList = ref([])
var measureIdx = ref('')
var measureRtsm = ref('')
var newMeasure = ref([])

// 动态数据
const num = ref()

watch(newMeasure, (newVal, oldVal) => {
  // console.log(newVal, 'newVal');
}, { deep: true })

watch(indexMeasureList, (newVal, oldVal) => {
  // console.log(newVal, 'watchindexMeasureList');
  newVal.forEach(e => {
    if (e.desc == '一号液位' && document.getElementById('Yhyw')) {
      document.getElementById('Yhyw').innerHTML = "<div>一号液位:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '二号液位' && document.getElementById('Ehyw')) {
      document.getElementById('Ehyw').innerHTML = "<div>二号液位:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '总压力' && document.getElementById('Zyl')) {
      document.getElementById('Zyl').innerHTML = "<div>总压力:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '五号泵压力' && document.getElementById('Whbyl')) {
      document.getElementById('Whbyl').innerHTML = "<div>五号泵压力:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '瞬时流量' && document.getElementById('Ssll')) {
      document.getElementById('Ssll').innerHTML = "<div>瞬时流量:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '五号电流反馈' && document.getElementById('dianliu')) {
      document.getElementById('dianliu').innerHTML = "<div>五号电流反馈:" + e.value.toFixed(3) +  "</div>"
    }
    if (e.desc == '五号频率反馈' && document.getElementById('pinlv')) {
      document.getElementById('pinlv').innerHTML = "<div>五号频率反馈:" + e.value.toFixed(3) +  "</div>"
    }
  })
}, { deep: true })
//login

const loginClick = async () => {
  const res = await loginApi({
    cmd: 'login',
    account: 'work',
    pwd: 'work@123'
  })
  // console.log(res);
}

onMounted(() => {
  loginClick()
  setTimeout(async () => {
    //1.获取初始化数据
    await getMeasureList()
    measureIdx.value = registerClick(indexMeasureList.value)
    getMeasureRtsmReq()
  }, 1000);
})

const init3d = (measureData, statusData) => {
  // console.log(measureData, statusData)
  // console.log(indexMeasureList.value, 'measureData1997');
  // console.log(indexStatusList.value, 'statusData1997');
  // 旧材质
  let oldYhywMat, oldEhywMat, oldSsllMat, oldWaterMat, waterRun
  // 新材质
  // const redMat = new THREE.MeshBasicMaterial({ color: 0xff0000 })
  const redMat = new THREE.MeshBasicMaterial({ color: 0x8b0000 })
  const yellowMat = new THREE.MeshBasicMaterial({ color: 0xff6600 })
  const greenMat = new THREE.MeshBasicMaterial({ color: 0x22652A })
  const grayMat = new THREE.MeshBasicMaterial({ color: 0x333333 })
  const newWaterMat = new THREE.MeshPhysicalMaterial({ color: 0x22652A, map: new THREE.TextureLoader().load('./map.jpg') });
  const waterStop = new THREE.TextureLoader().load('./map.jpg')
  // 场景
  const scene = new THREE.Scene()
  const loadingManager = new THREE.LoadingManager()
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
  camera.position.set(-20, 20, -20)
  const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true, logarithmicDepthBuffer: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.getElementById("scene").appendChild(renderer.domElement)
  const labelRenderer = new CSS2DRenderer()
  labelRenderer.setSize(window.innerWidth, window.innerHeight)
  document.getElementById("scene").appendChild(labelRenderer.domElement)
  labelRenderer.domElement.style.position = 'absolute'
  labelRenderer.domElement.style.bottom = '0px'
  labelRenderer.domElement.style.left = '0px'
  labelRenderer.domElement.style.pointerEvents = 'none'

  new RGBELoader().load('./HDR.hdr', (texture) => {
    texture.mapping = THREE.EquirectangularRefractionMapping
    renderer.toneMapping = THREE.ACESFilmicToneMapping
    renderer.toneMappingExposure = 4
    scene.background = new THREE.Color(0x041035) //设置背景色
    scene.environment = texture
  })

  const controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true

  const render = () => {
    controls.update()
    renderer.render(scene, camera)
    labelRenderer.render(scene, camera)
    requestAnimationFrame(render)
    scene.traverse(obj => {
      if (obj.isMesh && obj.name.includes('管道-流动')) {
        obj.material.map.offset.y += 0.001
      }
    })
  }
  render()

  const creatLabel = (name, desc, value, color = null) => {
    const labelDiv = document.createElement('div');
    labelDiv.className = "labeldiv"
    labelDiv.innerHTML = `<div>${desc}: ${value}</div>`
    const labeldiv = new CSS2DObject(labelDiv)
    const pos = scene.getObjectByName(name).position
    labeldiv.position.set(pos.x, pos.y + .5, pos.z)
    if (color) {
      labelDiv.style.color = color
      labelDiv.style.backgroundColor = color
      labelDiv.style.border = color
    }
    labelDiv.id = name
    scene.add(labeldiv)
  }

  const creatWarring = () => {
    const labelDiv = document.createElement('div')
    labelDiv.className = "labelWarring"
    labelDiv.innerHTML = ` <div>检修</div> `
    const labeldiv = new CSS2DObject(labelDiv)
    const pos = scene.getObjectByName('大电机').position
    labeldiv.position.set(pos.x, pos.y + .5, pos.z)
    scene.add(labeldiv)
  }

  const onWindowReset = () => {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
    labelRenderer.setSize(window.innerWidth, window.innerHeight)
  }

  const loading = () => {
    // 加载进度
    var jindu_text_con = document.getElementById('jindu-text-con')
    var jindu_text = document.getElementById('jindu-text')
    var jindu = document.getElementById('jindu')

    let i = 0
    const tim = setInterval(() => {
      if (i < 89) {
        i += Math.random()
        jindu_text.innerText = Math.floor(i) + '%'
        jindu.style.width = Math.floor(i) + '%'
      } else {
        clearInterval(tim)
      }
    }, 300);
    loadingManager.onProgress = (url, itemsLoaded, itemsTotal) => {
      let _onProgress = Math.floor(itemsLoaded / itemsTotal * 100)
      if (_onProgress == 100) {
        jindu_text_con.style.display = 'none'
      }
    }
  }
  const initData = (modelScene) => {
    // console.log(measureData, statusData)
    
    if (measureData.length > 0) {
      for (let i = 0; i < measureData.length; i++) {
        const item = measureData[i];
        // console.log(item)
        if (item.desc === '一号液位') {
          creatLabel('Yhyw', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '二号液位') {
          creatLabel('Ehyw', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '总压力') {
          creatLabel('Zyl', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '五号泵压力') {
          creatLabel('Whbyl', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '瞬时流量') {
          creatLabel('Ssll', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '五号电流反馈') {
          creatLabel('dianliu', item.desc, item.value.toFixed(3))
        }
        if (item.desc === '五号频率反馈') {
          creatLabel('pinlv', item.desc, item.value.toFixed(3))
        }
      }
    }
    if (statusData.length > 0) {
      statusData.forEach(e => {
        /* -----------------------其他--------------------*/
        // 急停按钮
        if (e.name === "Tbdzsbf.Jtan") {
          // 0正常灰色，1急停红色
          if (e.value === 2) {
            document.getElementById('Jtan').style.backgroundColor = 'red'
          } else {
            document.getElementById('Jtan').style.backgroundColor = 'gray'
          }
        }
        // 浸水信号
        if (e.name === "Tbdzsbf.Jsxh") {
          // 前端显示，实时显示，0绿色1红色（字体提示，泵房浸水）
          if (e.value === 2) {
            document.getElementById('Jsxh').style.backgroundColor = 'red'
          } else {
            document.getElementById('Jsxh').style.backgroundColor = 'gray'
          }
        }
        // 系统有故障
        if (e.name === "Tbdzsbf.Xtygz") {
          // 前端显示，实时显示，0绿色1红色（字体提示，泵房浸水）
          if (e.value === 2) {
            document.getElementById('Xtygz').style.backgroundColor = 'red'
          } else {
            document.getElementById('Xtygz').style.backgroundColor = 'gray'
          }
        }
        // 五号泵检修
        if (e.name === "Tbdzsbf.Whbjx") {
          // 1检修0启用  前端显示，泵体上显示检修字样 红色字体黄色背景
          if (e.value === 2) {
            creatWarring()
          }
        }
        /* -----------------------五号泵--------------------*/
        // 五号泵变频器运行反馈Whbbpqyxfk
        if (e.name == "Tbdzsbf.Whbbpqyxfk") {
          console.log(e.value, 'Whbbpqyxfk--变频运行');
          // 0灰色1黄色
          const model = modelScene.getObjectByName('大电机')
          // if (e.value === 1) {
          //   model.material = grayMat
          //   modelScene.traverse(obj => {
          //     if (obj.isMesh && obj.name.includes('管道-流动')) {
          //       obj.material = newWaterMat
          //     }
          //   })
          // } else if (e.value === 2) {
          //   model.material = yellowMat
          //   creatLabel('大电机top', '提示', '变频运行')
          //   modelScene.traverse(obj => {
          //     if (obj.isMesh && obj.name.includes('管道-流动')) {
          //       obj.material = oldWaterMat
          //     }
          //   })
          // }
          if (e.value === 2) {
            model.material = yellowMat
            creatLabel('大电机top', '提示', '变频运行')
            modelScene.traverse(obj => {
              if (obj.isMesh && obj.name.includes('管道-流动')) {
                obj.material = oldWaterMat
              }
            })
          }
        }
        // 五号泵工频运行信号反馈
        if (e.name == "Tbdzsbf.Whbgpyxxhfk") {
          console.log(e.value, 'Whbgpyxxhfk');
          // 0灰色1绿色
          const model = modelScene.getObjectByName('大电机')
          // if (e.value == 1) {
          //   modelScene.traverse(obj => {
          //     if (obj.isMesh && obj.name.includes('管道-流动')) {
          //       obj.material.map = waterStop
          //     }
          //   })
          //   model.material = grayMat
          // } 
          if (e.value == 2) {
            modelScene.traverse(obj => {
              if (obj.isMesh && obj.name.includes('管道-流动')) {
                obj.material.map = waterRun
              }
            })
            model.material = greenMat
            creatLabel('大电机top', '提示', '工频运行')
          }
        }
        // 五号泵变频器故障反馈
        if (e.name === "Tbdzsbf.Whbbpqgzfk") {
          // 0灰色1红色
          const model = modelScene.getObjectByName('大电机')
          // if (e.value === 1) {
          //   model.material = grayMat
          // } else if (e.value === 2) {
          //   model.material = redMat
          //   creatLabel('大电机top', '提示', '变频故障')
          // }
          if (e.value === 2) {
            model.material = redMat
            creatLabel('大电机top', '提示', '变频故障')
          }
        }
        // 五号泵工频故障信号反馈
        if (e.name == "Tbdzsbf.Whbgpgzxhfk") {
          console.log(e.value, 'Whbgpgzxhfk--工频故障');
          // 0灰色1红色
          const model = modelScene.getObjectByName('大电机')
          // if (e.value == 1) {
          //   modelScene.traverse(obj => {
          //     if (obj.isMesh && obj.name.includes('管道-流动')) {
          //       obj.material.map = waterStop
          //     }
          //   })
          //   model.material = grayMat
          // } 
          if (e.value == 2) {
            modelScene.traverse(obj => {
              if (obj.isMesh && obj.name.includes('管道-流动')) {
                obj.material.map = waterRun
              }
            })
            model.material = redMat
            creatLabel('大电机top', '提示', '工频故障')
          }
        }

        
        /* -----------------------------------------------*/
        // 一号液位高报警
        if (e.name === "Tbdzsbf.Yhywgbj") {
          // 0灰色1红色
          const model = modelScene.getObjectByName('Yhyw')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = redMat
          }
        }
        // 一号液位低报警
        if (e.name === "Tbdzsbf.Yhywdbj") {
          // 0灰色1黄色
          const model = modelScene.getObjectByName('Yhyw')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = yellowMat
          }
        }
        // 二号液位高报警
        if (e.name === "Tbdzsbf.Ehywgbj") {
          // 0灰色1红色
          const model = modelScene.getObjectByName('Ehyw')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = redMat
          }
        }
        // 二号液位低报警
        if (e.name === "Tbdzsbf.Ehywdbj") {
          // 0灰色1黄色
          const model = modelScene.getObjectByName('Ehyw')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = yellowMat
          }
        }
        // 五号泵压力高报警
        if (e.name === "Tbdzsbf.Whbylgbj") {
          // 0灰色1绿色
          const model = modelScene.getObjectByName('Whbyl')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = greenMat
          }
        }
        // 五号泵压力低报警
        if (e.name === "Tbdzsbf.Whbyldbj") {
          // 0灰色1绿色
          const model = modelScene.getObjectByName('Whbyl')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = yellowMat
          }
        }
        // 总压力高报警
        if (e.name === "Tbdzsbf.Zylgbj") {
          // 0灰色1绿色
          const model = modelScene.getObjectByName('Zyl')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = greenMat
          }
        }
        // 总压力低报警
        if (e.name === "Tbdzsbf.Zyldbj") {
          // 0灰色1绿色
          const model = modelScene.getObjectByName('Zyl')
          if (e.value === 1) {
            model.material = grayMat
          } else if (e.value === 2) {
            model.material = yellowMat
          }
        }
      })
    }
  }

  const dracoLoader = new DRACOLoader()
  dracoLoader.setDecoderPath("./draco/")
  // dracoLoader.setDecoderPath("../public/draco/")
  new GLTFLoader(loadingManager).setDRACOLoader(dracoLoader).load('./modelD.glb', gltf => {
      scene.add(gltf.scene)
      oldYhywMat = scene.getObjectByName('Yhyw').material
      oldEhywMat = scene.getObjectByName('Ehyw').material
      oldSsllMat = scene.getObjectByName('Ssll').material
      oldWaterMat = scene.getObjectByName('管道-流动').material
      waterRun = scene.getObjectByName('管道-流动').material.map
      initData(gltf.scene)
  })
  
}


// 去掉字符串倒数第一个逗号
function removeLastComma(str) {
  const lastIndex = str.lastIndexOf(",");
  if (lastIndex === -1) return str; // 如果没有找到逗号，返回原字符串
  return str.substring(0, lastIndex) + str.substring(lastIndex + 1);
}
// 获取初始化indexMeasureList
const getMeasureList = async () => {
  const formData = {
    name: "Tbdzsbf.Yhyw*Tbdzsbf.Ehyw*Tbdzsbf.Zyl*Tbdzsbf.Whbyl*Tbdzsbf.Ssll*Tbdzsbf.Whplfk*Tbdzsbf.Whdlfk",
    type: 'measure'
  }
  const res = await startGetListApi(formData)
  const fixedString = removeLastComma(res.data)
  const jsonObj = JSON.parse(fixedString);

  indexMeasureList.value = jsonObj.rows
  // console.log(indexMeasureList.value, 'indexMeasureList');
}

// 去掉JSON字符串中最后两个逗号的方法
function removeLastTwoCommas(jsonString) {
  // 使用正则表达式匹配最后两个逗号并替换为空字符串
  return jsonString.replace(/,(?=[^,]*$)/, '').replace(/,(?=[^,]*$)/, '');
}
//获取measure追踪数据rtsm
const getMeasureRtsmReq = async () => {
  const formData = {
    cmd: "reg",
    measureIdx: measureIdx.value
  }
  const res = await registerApi(formData)
  const RtsmFixedString = removeLastTwoCommas(res.data)
  const RtsmJsonObj = JSON.parse(RtsmFixedString);
  measureRtsm.value = RtsmJsonObj.rtsm
  newMeasure.value = RtsmJsonObj.measure
  // console.log(newMeasure, 'newMeasure');
  //轮训调取
  setInterval(() => {
    getMeasureNewReq()
  }, 1000);
}
//轮询获取newMeasure数据 并更新 indexMeasureList
const getMeasureNewReq = async () => {
  const formData = {
    cmd: "query",
    rtsm: measureRtsm.value
  }
  const res = await pollApi(formData)
  const RtsmFixedString2 = removeLastTwoCommas(res.data)
  const RtsmJsonObj2 = JSON.parse(RtsmFixedString2)
  newMeasure.value = RtsmJsonObj2.measure
  // console.log(RtsmJsonObj2, 'RtsmJsonObj2');

  const deepCopyNewMeasure = _.cloneDeep(newMeasure.value)
  const deepCopyIndexMeasureList = _.cloneDeep(indexMeasureList.value)
  const alllist = changeListVue(deepCopyNewMeasure, deepCopyIndexMeasureList)
  // console.log(alllist, 'alllist111111111111');
  indexMeasureList.value = alllist

// console.log(indexMeasureList.value, 'indexMeasureList轮训修改');

  // changeListMeasure()
  // console.log(indexMeasureList.value, 'indexMeasureList轮训修改');
}


var indexStatusList = ref([])
var statusIdx = ref('')
var statusRtsm = ref('')
var newStatus = ref([])
onMounted(() => {
  setTimeout(async () => {
    //1.获取初始化数据
    await getStatusList()
    statusIdx.value = registerClick(indexStatusList.value)
    getStatusRtsmReq()

    init3d(indexMeasureList.value, indexStatusList.value)
    // console.log(indexMeasureList.value, 'indexMeasureList');
    // console.log(indexStatusList.value, 'indexStatusList');
  }, 1000);
})
//获取初始化indexStatusList
const getStatusList = async () => {
  const formData = {
    name: "Tbdzsbf.Xyan*Tbdzsbf.Jtan*Tbdzsbf.Whbgpyxxhfk*Tbdzsbf.Whbgpgzxhfk*Tbdzsbf.Whbbpqyxfk*Tbdzsbf.Whbbpqgzfk*Tbdzsbf.Jsxh*Tbdzsbf.Jrxh*Tbdzsbf.Lxjbj*Tbdzsbf.Plcgkmxh*Tbdzsbf.Plcgddxh*Tbdzsbf.Whbjx*Tbdzsbf.Xtygz*Tbdzsbf.Yhywgbj*Tbdzsbf.Yhywdbj*Tbdzsbf.Ehywgbj*Tbdzsbf.Ehywdbj*Tbdzsbf.Whbylgbj*Tbdzsbf.Whbyldbj*Tbdzsbf.Zylgbj*Tbdzsbf.Zyldbj",
    type: 'status'
  }
  const res = await startGetListApi(formData)
  const fixedString2 = removeLastComma(res.data)
  const jsonObj2 = JSON.parse(fixedString2);
  indexStatusList.value = jsonObj2.rows

}
//获取status追踪数据rtsm
const getStatusRtsmReq = async () => {
  const formData = {
    cmd: "reg",
    statusIdx: statusIdx.value
  }
  const res = await registerStatusApi(formData)
  const RtsmFixedString = removeLastTwoCommas(res.data)
  const RtsmJsonObj = JSON.parse(RtsmFixedString);

  statusRtsm.value = RtsmJsonObj.rtsm
  newStatus.value = RtsmJsonObj.status
  // 轮训调取
  setInterval(() => {
    getStatusNewReq()
  }, 5000);
}
//轮询获取newStatus数据 并更新 indexStatusList
const getStatusNewReq = async () => {
  const formData = {
    cmd: "query",
    rtsm: statusRtsm.value
  }
  const res = await pollApi(formData)
  const RtsmFixedString2=removeLastTwoCommas(res.data)
  const RtsmJsonObj2=JSON.parse(RtsmFixedString2);
  newStatus.value = RtsmJsonObj2.status
  // console.log(res.data, 'newStatus');
  //修改原数组
  const deepCopyNewStatus = _.cloneDeep(newStatus.value)
  const deepCopyIndexStatusList = _.cloneDeep(indexStatusList.value)
  const alllist = changeListVue(deepCopyNewStatus, deepCopyIndexStatusList)
// console.log(alllist, 'alllist2222222222222');
  indexStatusList.value = alllist
  // console.log(indexStatusList.value, 'indexStatusList轮训修改');

}
//2.注册数据追踪
const registerClick = (arr) => {

  const str = getIdx(arr)
  // console.log(str, 'str');
  return str
}
const changeListMeasure = () => {
  newMeasure.value.forEach((item, index) => {
    indexMeasureList.value.forEach((e, i) => {
      if (item.idx === e.idx) {
        indexMeasureList.value[i].value = item.value
      }
    })
  })
}

const changeListVue = (newList, oldList) => {
  //返回修改后的数组
  const newlist = newList
  const newoldlist = [...oldList]
  newlist.forEach((item, index) => {
    newoldlist.forEach((e, i) => {
      if (item.idx === e.idx) {
        newoldlist[i].value = item.value
      }
    })
  })
  return newoldlist
}


</script>

<style>
.labeldiv {
  line-height: 18px;
  border-radius: 8px;
  padding: 1px 5px;
  color: #0ae9e7;
  border: 1px #00ffff solid;
  font-size: 12px;
  text-align: left;
  background-color: rgba(0, 0, 0, 0.8);
}

.labelWarring {
  line-height: 18px;
  padding: 20px;
  color: #f00;
  font-size: 36px;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  /* background-color:rgba(255, 255, 255, 0.8); */
}

.alter {
  z-index: 999;
  position: fixed;
  top: 100px;
  right: 100px;
  padding: 20px 40px !important;
  line-height: 56px !important;
  font-size: 33px !important;
  font-weight: bold !important;
  pointer-events: none;
}

.labelitem {
  display: flex;
  align-items: center;
}

.dot {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  /* background-color: #ff0000; */
}
</style>